﻿using System.Collections.Generic;
using System.Linq;
using QFramework;

namespace System.GunSystem
{
    public interface IGunSystem : ISystem
    {
        GunInfo CurrentGun { get; }

        Queue<GunInfo> GunInfos { get; }

        void PickGun(string name, int bulletCountInGun, int bulletCountOutGun);

        void ShiftGun();
    }

    public class OnCurrentGunChanged
    {
        public string Name { get; set; }
    }

    public class GunSystem : AbstractSystem, IGunSystem
    {
        public GunInfo CurrentGun { get; } = new()
        {
            BulletCountInGun = new BindableProperty<int>
            {
                Value = 3
            },
            BulletCountOutGun = new BindableProperty<int>
            {
                Value = 1
            },
            Name = new BindableProperty<string>
            {
                Value = "手枪"
            },
            GunState = new BindableProperty<GunState>
            {
                Value = GunState.Idle
            }
        };

        public Queue<GunInfo> GunInfos { get; } = new();

        public void PickGun(string name, int bulletCountInGun, int bulletCountOutGun)
        {
            if (CurrentGun.Name.Value == name)
            {
                // 当前枪是同类型
                CurrentGun.BulletCountInGun.Value += bulletCountInGun;
                CurrentGun.BulletCountOutGun.Value += bulletCountOutGun;
            }
            else if (GunInfos.Any(info => info.Name.Value == name))
            {
                // 已经拥有这把枪
                var gunInfo = GunInfos.First(info => info.Name.Value == name);

                gunInfo.BulletCountInGun.Value += bulletCountInGun;
                gunInfo.BulletCountOutGun.Value += bulletCountOutGun;
            }
            else
            {
                EnQueueCurrentGun(name, bulletCountInGun, bulletCountOutGun);
            }
        }

        public void ShiftGun()
        {
            if (GunInfos.Count > 0)
            {
                var nextGunInfo = GunInfos.Dequeue();

                EnQueueCurrentGun(nextGunInfo.Name.Value, nextGunInfo.BulletCountInGun.Value,
                    nextGunInfo.BulletCountOutGun.Value);
            }
        }

        /// <summary>
        ///     将当前枪入队列，替换新枪，发送换枪事件
        /// </summary>
        /// <param name="nextGunName"></param>
        /// <param name="nextGunBulletCountInGun"></param>
        /// <param name="nextGunBulletCountOutGun"></param>
        private void EnQueueCurrentGun(string nextGunName, int nextGunBulletCountInGun, int nextGunBulletCountOutGun)
        {
            // 复制当前的枪械信息
            var currentGunInfo = new GunInfo
            {
                Name = new BindableProperty<string>
                {
                    Value = CurrentGun.Name.Value
                },
                BulletCountInGun = new BindableProperty<int>
                {
                    Value = CurrentGun.BulletCountInGun.Value
                },
                BulletCountOutGun = new BindableProperty<int>
                {
                    Value = CurrentGun.BulletCountOutGun.Value
                },
                GunState = new BindableProperty<GunState>
                {
                    Value = CurrentGun.GunState.Value
                }
            };

            // 缓存
            GunInfos.Enqueue(currentGunInfo);

            // 新枪设置为当前枪
            CurrentGun.Name.Value = nextGunName;
            CurrentGun.BulletCountInGun.Value = nextGunBulletCountInGun;
            CurrentGun.BulletCountOutGun.Value = nextGunBulletCountOutGun;
            CurrentGun.GunState.Value = GunState.Idle;

            // 发送换枪事件
            this.SendEvent(new OnCurrentGunChanged
            {
                Name = nextGunName
            });
        }

        protected override void OnInit()
        {
        }
    }
}